home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d17 / lp_oki.arc / LP14.ASM next >
Assembly Source File  |  1985-08-16  |  14KB  |  675 lines

  1.     Title    LP - Print File With Pagination
  2.     Page    80,132
  3.     Comment    |
  4.  
  5. LP Command
  6. ________________
  7.  
  8. Purpose:  To print an ASCII file on the standard printer
  9.       device at either 66 or 88 lines per page. A title
  10.       is printed at the top of each page which contains
  11.       the file name, creation date, and page number.
  12.  
  13. Syntax:      LP [d][path]filename[.ext]    [/6][/8]
  14.                     [/L1][/L2]
  15.                     [/10][/12][/17]
  16.  
  17. Remarks:
  18.       Written by Vernon Buerg for the IBM PC using
  19.       DOS 2.0 or later. For public domain use. Not
  20.       for sale or hire.
  21.  
  22.       Version 1.1, April 27, 1984.
  23.       Version 1.2, Sept 12, 1984.
  24.       Version 1.4, Aug 8, 1985.
  25.         - account for TABs and long lines
  26.         - remove Int 17h due to bad spoolers
  27. ________________                            |
  28.  
  29. Cseg    Segment    Public Para 'CODE'
  30.     Assume    CS:Cseg,DS:Cseg
  31.     Org    100h
  32.  
  33. LP    Proc    Far
  34.     Mov    SP,Offset CS:Lstack    ;Use local stack
  35.  
  36.     Push    DS            ;For DOS return
  37.     Sub    AX,AX
  38.     Push    AX
  39.     Mov    Stk_Top,SP
  40.  
  41.     Call    Ver            ; Check DOS version
  42.  
  43.     Call    Alloc            ; Allocate memory
  44.  
  45.     Call    GetFile            ; Get file name
  46.  
  47.     Call    Opens            ; Open input
  48.  
  49.     Call    InitLPT            ; Initialize printer
  50.  
  51.     Call    GetName            ; Format title line
  52.  
  53.     Call    Titles            ; and print it
  54.  
  55.     Call    List            ; Print the file
  56.  
  57.     Call    Flush            ; Drain the output buffer
  58.  
  59. Eod:    Mov    DX,Offset EofMsg    ;Say END-OF-FILE
  60.     Jmp    Fini
  61.  
  62. Error:    Mov    CS:Errlvl,1
  63. Fini:    Mov    AX,CS            ;Insure seg regs
  64.     Mov    DS,AX
  65.     Mov    SP,Stk_Top        ; and stackck
  66.  
  67.     Mov    AH,9            ;Print error message
  68.     Int    21h
  69.  
  70.     Mov    BX,IHandle        ;Close input
  71.     Mov    AH,3Eh
  72.     Int    21h
  73.  
  74.     Mov    BX,OHandle        ; Close output
  75.     Cmp    BX,4            ;  if not standard output
  76.     Je    Exit
  77.     Mov    AH,3Eh
  78.     Int    21h
  79. Exit:
  80.     Mov    AL,Errlvl        ; Set ERROR LEVEL
  81.     Mov    AH,4Ch            ; and Exit
  82.     Int    21h
  83.     Page
  84. ;
  85. ;    Constants and Data Areas
  86.  
  87. BEL    Equ    07
  88. BS    Equ    08
  89. TAB    Equ    09
  90. LF    Equ    10
  91. FF    Equ    12
  92. CR    Equ    13
  93. EOF    Equ    1Ah
  94. ESC    Equ    1Bh
  95.  
  96. Buflen    Dw    0            ;I/O buffer size (variable)
  97. Stk_Top    Dw    0            ;Stack ptr at entry
  98.  
  99. Lcnt    Db    0            ;Line counter
  100. Cpp    Db    96            ;Chars per page
  101. LPP    Db    82            ;Lines per page
  102. LPTn    Dw    0            ;Printer port
  103. Errlvl    Db    0            ;Error level returned
  104. Ccnt    Db    0            ;Chars in current line
  105.  
  106. MsgIn    Db    CR,LF,'Enter INPUT filename  $'
  107. Msg1    Db    CR,LF,'Unable to open input'
  108. InKey    Db    32,32            ;Keyboard buffer
  109. Input    Db    76 Dup (0),'$'        ;Drive:path\name.ext
  110. IHandle    Dw    0            ;Input file handle
  111. Ilen    Dw    0            ;Input block length
  112. Iptr    Dw    0            ;Offset    to next    char
  113. InPtr    Dw    0            ;Offset to input buffer
  114.  
  115.  
  116. Msg2    Db    CR,LF,'Unable to open LPT'
  117. Msg2a    Db    '1$'
  118. Output    Db    'LPT1:',0,'$'        ;Printer name
  119. OHandle    Dw    0            ;Output file handle
  120. Olen    Dw    0            ;Output block length
  121. Optr    Dw    0            ;Offset    to next    char
  122. OutPtr    Dw    0            ;Offset to output buffer
  123.  
  124. OutChar    Db    0
  125.  
  126. AlocMsg    Db    CR,LF,'Not enough memory',CR,LF,BEL,'$'
  127. ErrMsg    Db    CR,LF,'Invalid command option(s)',CR,LF,BEL,'$'
  128. Version    Db    'LP - Version 1.4 - V.Buerg',CR,LF,'$'
  129. Sorry    Db    'Sorry, PC DOS 2.0 or later required',CR,LF,BEL,'$'
  130.  
  131. Heading    Db    CR            ;Top line title
  132. FileNm    Db    43 Dup (' ')
  133. Date    Db    'mm-dd-yy',9,9
  134.     Db    'Page  '
  135. Pageno    Db    '1',LF
  136.  
  137. EofMsg    Db    CR,LF
  138. Len_H    Equ    This Byte - Heading
  139.     Db    'End of File',CR,LF,'$'
  140.  
  141. Dater    Record    Yr:7,Mo:4,Dy:5
  142.  
  143. Reset    Db    CR            ;Printer initialization codes
  144.     Db    FF,ESC            ;Form feed (no CPI setting)
  145. Lpi    Db    56            ;Lines per inch
  146. Cpi    Db    28            ;Chars per inch
  147.  
  148. Tabs    Db    ESC,TAB
  149.     Db    '009,017,025,033,041,049,057,065,073'
  150. Reset10 Equ    $-Reset+1
  151. Tabs12    Db    ',081,089'        ; When using 12-cpi
  152. Reset12 Equ    $-Reset+1
  153. Tabs17    Db    ',097,105,113,121,129',CR
  154. Reset17    Equ    $-Reset
  155.  
  156. Reset_L    Dw    Reset12            ; Length of initial string
  157.     Page
  158. ;
  159. ;    Copy file to printer
  160.  
  161. List    Proc    Near
  162.  
  163. List1:    Call    Read            ;Get one character
  164.     And    AL,7FH            ;Strip hi-order    bit
  165.  
  166.     Cmp    AL,FF            ;Is it form feed?
  167.     Je    Eject
  168.  
  169.     Cmp    AL,LF            ;Pass line feed
  170.     Je    Passit
  171.  
  172.     Cmp    AL,CR            ;Pass carriage return
  173.     Je    Passit
  174.  
  175.     Cmp    AL,BS            ;Pass back space
  176.     Je    PassBS
  177.  
  178.     Cmp    AL,TAB            ;Pass tab chars
  179.     Je    PassTAB
  180.     Inc    Ccnt            ;Incr count of chars in line
  181.  
  182.     Cmp    AL,EOF            ;End of    file?
  183.     Je    Done
  184.  
  185.     Cmp    AL,32            ;Other control char?
  186.     Jns    Passit
  187.     Jmp    CtlChr
  188.  
  189. PassTAB:Add    Ccnt,8            ;Round up to TAB column
  190.     And    Ccnt,0F8h
  191.     Jmp    Passit
  192.  
  193. PassBS:    Dec    Ccnt            ;Account for backspace
  194.     Jns    Passit
  195.     Mov    Ccnt,0
  196.  
  197. Passit:    Call    PutChar
  198.     Mov    AH,Cpp            ;Max chars per line
  199.     Cmp    Ccnt,AH            ; filled up a line?
  200.     Ja    Passit2
  201. Passit1:
  202.     Cmp    AL,LF            ;Is it line feed?
  203.     Jne    List1            ; no, get next char
  204. Passit2:
  205.     Inc    Lcnt            ; yes, incr line count
  206.     Mov    Ccnt,0
  207.     Mov    AL,Lcnt
  208.     Cmp    AL,LPP            ;End of    page?
  209.     Jb    List1            ; no, get next char
  210.  
  211. Eject:    Mov    Ccnt,0            ;Reset char count in line
  212.     Cmp    Lcnt,2            ;Printed any lines yet?
  213.     Jbe    List1            ; no, ignore form feed
  214.     Call    NewPage
  215.     Jmp    List1            ;Get next record
  216.  
  217. CtlChr:    Cmp    AL,0            ;Null char?
  218.     Je    Blanks            ; yes, make it a space
  219.     Push    AX
  220.     Mov    AL,'^'            ;Indicate a control char
  221.     Call    PutChar
  222.     Inc    Ccnt
  223.     Pop    AX                 ;Get char again
  224. Blanks:    Add    AL,20H            ;Make it printable
  225.     Jmp    Passit
  226.  
  227. Done:    Ret
  228. List    Endp
  229.     Page
  230. ;
  231. ;    Process end of page
  232.  
  233. NewPage    Proc    Near
  234.     Cmp    Lcnt,2            ;Is it title line?
  235.     Je    Titles            ; yes, skip rest
  236.     Mov    AL,CR
  237.     Call    PutChar            ; no, send CR
  238.     Mov    AL,FF
  239.     Call    PutChar            ; and form feed
  240.     Mov    Lcnt,0            ;Reset line count
  241.  
  242.     Push    DI
  243.     Mov    DI,Offset Pageno
  244.     Mov    AX,3A30h
  245. Next:    Inc    Byte Ptr [DI]        ;Incr page number
  246.     Cmp    [DI],AL            ;End in    zero?
  247.     Js    Set1            ; yes, make it a one
  248.     Cmp    [DI],AH            ;Over nine?
  249.     Jne    PgSet            ; no, have good number
  250.     Mov    [DI],AL            ; yes, make last digit zero
  251.     Dec    DI            ; and incr hi-order
  252.     Jmp    Next
  253.  
  254. Set1:    Mov    Byte Ptr [DI],'1'
  255. PgSet:    Pop    DI
  256.  
  257. ;
  258. ;    Print top line titles
  259.  
  260. Titles:    Mov    SI,Offset Heading    ;Print title line
  261.     Mov    CX,Len_H
  262. Next1:    Lodsb
  263.     Cmp    AL,0            ;Replace nulls
  264.     Jne    Next2
  265.     Mov    AL,' '
  266. Next2:    Call    PutChar
  267.     Loop    Next1
  268.     Mov    Lcnt,2            ;Reset line counter
  269.     Ret
  270.  
  271. ;
  272. ;    Initialize the printer
  273.  
  274. InitLPT    Proc    Near            ;Initialize the printer
  275. Init1:    Mov    CX,Reset_L        ;Length of
  276.     Mov    SI,Offset Reset        ; initial codes
  277. Init2:    Call    Next1
  278.     Ret
  279. InitLPT    Endp
  280.  
  281. NewPage    Endp
  282.  
  283.     Page
  284. ;
  285. ;    Format title line
  286.  
  287. GetName    Proc    Near            ;Format title line
  288.     Mov    SI,Offset Input        ;Copy file name
  289.     Mov    DI,Offset Filenm    ; to heading
  290.     Mov    CX,42            ;Max for title
  291.     Cld
  292.     Repz    Movsb
  293.  
  294.     Mov    AX,5700h        ;Return file's date and time
  295.     Mov    BX,IHandle        ;Input handle
  296.     Int    21h
  297.  
  298.     Mov    DI,Offset Date        ;Date field in title
  299.  
  300.     Mov    AX,DX            ;Get month part
  301.     And    AX,Mask Mo
  302.     Mov    CL,Mo
  303.     Call    Format
  304.     Stosw
  305.     Inc    DI            ;Add delimiter
  306.  
  307.     Mov    AX,DX            ;Get day part
  308.     And    AX,Mask Dy
  309.     Mov    CL,Dy
  310.     Call    Format
  311.     Stosw
  312.     Inc    DI            ;Add delimiter
  313.  
  314.     Mov    AX,DX            ;Get year part
  315.     And    AX,Mask Yr
  316.     Mov    CL,Yr
  317.     Call    Format
  318.     Or    AL,'8'
  319.     Stosw
  320.     Ret
  321. GetName    Endp
  322.  
  323. Format    Proc    Near            ;Convert binary to ASCII
  324.     Shr    AX,CL
  325.     Aam
  326.     Or    AX,'00'
  327.     Xchg    AH,AL
  328.     Ret
  329. Format    Endp
  330.     Page
  331. ;
  332. ;    Extract one char from record
  333.  
  334. Read    Proc    Near            ;Read char into    AL
  335. Read1:    Cmp    Ilen,0            ;Any in    buffer?
  336.     Je    Read2            ; no, read next    block
  337.     Mov    SI,Iptr            ; yes, get offset in buf
  338.     Lodsb
  339.     Inc    Iptr            ;Offset    for next one
  340.     Dec    Ilen            ;Decr buffer size left
  341.     Ret                ; and return
  342.  
  343. Read2:    Mov    BX,IHandle        ;Read input
  344.     Mov    CX,BufLen
  345.     Mov    DX,InPtr        ;Set up    DS:DX
  346.     Mov    AH,3Fh
  347.     Int    21h            ;Read a    block
  348.     Mov    DX,InPtr
  349.     Mov    Iptr,DX            ;Reset buffer ptr
  350.     Mov    Ilen,AX            ; and length
  351.     Jc    Read8
  352.     Or    AX,AX            ;Anything read?
  353.     Jnz    Read1            ; yes, pick it up
  354.     Mov    AL,EOF            ; no, return EOF
  355.     Ret
  356.  
  357. Read8:    Mov    DX,Offset Msg3        ;Say I/O ERROR
  358.     Jmp    Error
  359.  
  360. Msg3    Db    CR,LF,'I/O error',CR,LF,BEL,'$'
  361. Read    Endp
  362.  
  363. ;
  364. ;    Buffer characters to printer
  365.  
  366. PutChar    Proc    Near            ;Write from AL
  367.     Mov    DI,Optr            ; Spot for next outchar
  368.     Stosb
  369.     Mov    Optr,DI
  370.     Dec    Olen            ; Is it full now?
  371.     Jz    PutCh0            ; yes, print the lot
  372.     Ret
  373.  
  374. Flush:    Mov    AX,Olen            ; Bytes left in output buffer
  375.     Sub    Buflen,AX        ;  to get count in buffer
  376.     Jnz    PutCh0
  377.     Ret
  378.  
  379. PutCh0:    Push    AX
  380.     Push    BX
  381.     Push    CX
  382.     Push    DX
  383. PutCh1:    Mov    BX,OHandle        ; Printer file handle
  384.     Mov    CX,Buflen
  385.     Mov    Olen,CX            ; Reset size remaining in bufr
  386.     Mov    DX,OutPtr
  387.     Mov    Optr,DX            ; Reset ptr for next put
  388.     Mov    AH,40h            ; Print entire buffer
  389.     Int    21h
  390.     Jc    PutChe            ; Successful?
  391.     Cmp    AX,CX             ; Wrote it all?
  392.     Je    PutCh9
  393. PutChe:    Mov    DX,Offset MsgPut    ; Printer error
  394.     Or    MsgPute,AL
  395.     Jmp    Error
  396.  
  397. MsgPut    Db    'Printer error -- program terminated -- RC = '
  398. MsgPute    Db    '0',CR,LF,BEL,'$'
  399.  
  400. PutCh9:    Pop    DX
  401.     Pop    CX
  402.     Pop    BX
  403.     Pop    AX
  404.     Ret
  405. PutChar    Endp
  406.     Page
  407. ;
  408. ;    Get file names from parm
  409.  
  410. GetFile    Proc    Near            ;Get file name(s)
  411.     Mov    SI,80h            ;Point to command line
  412.     Sub    CX,CX            ;Clear length reg
  413.     Or    CL,Byte    Ptr [SI]    ;Get command tail length
  414.     Jz    GetF8            ; none, ask for them
  415.     Mov    DI,Offset Input        ;Point fname target
  416.     Inc    SI            ;Bump command ptr
  417.  
  418. GetF1:    Lodsb                ;Get next char
  419.     Cmp    AL,' '            ;Skip leading blanks
  420.     Jne    GetF2
  421.     Loope    GetF1
  422.     Jcxz    GetF8            ; all blank
  423.  
  424. GetF2:    Cmp    AL,CR            ;End of parm?
  425.     Je    GetF7            ; yes, terminate fname
  426.     Cmp    AL,' '            ;Delimiter?
  427.     Je    GetF4            ; yes, look for swithes
  428.     Cmp    AL,'/'            ;Switch char?
  429.     Je    GetF5
  430.     Stosb                ;Save fname char
  431.     Lodsb
  432.     Loop    GetF2
  433.     Jmp    GetF7
  434.  
  435. GetF4:    Dec    CX
  436.     Jz    GetF8
  437. GetF4a:    Lodsb
  438.     Cmp    AL,' '            ;Skip intervening blanks
  439.     Jne    GetF4b
  440.     Loope    GetF4a
  441.     Jcxz    GetF7            ; just trailing blanks
  442. GetF4b:    Cmp    AL,CR            ;End of parm?
  443.     Je    GetF7            ; yes, no switches
  444.     Jmp    Short GetF5b
  445.  
  446. GetF5:    Dec    CX
  447.     Jz    GetF7
  448. GetF5a:    Lodsb
  449. GetF5b:    Cmp    AL,'/'            ;Switch char?
  450.     Jne    GetFx            ; no, invalid
  451.     Dec    SI            ; yes, back up to it
  452.     Call    GetParm            ; and set switches
  453.  
  454. GetF7:
  455. GetF8:    Cmp    Input,0            ;Any input name?
  456.     Jne    GetF9            ; no, ask for it
  457.     Call    AskIn
  458. GetF9:    Ret
  459.  
  460. GetFx:    Mov    DX,Offset ErrMsg
  461.     Jmp    Error
  462.     Page
  463. ;
  464. ;    Determine switch parameters
  465.  
  466. GetParm    Proc    Near
  467.     Push    DI
  468.     Push    SI            ;Offset to parm string
  469.     Push    CX            ;Length of string
  470.  
  471.     Mov    DI,SI            ;Save string ptr
  472.     Add    DI,CX              ; ending offset
  473. GetP0:    Cmp    SI,DI            ;Any left?
  474.     Jb    GetP1
  475.     Jmp    GetP9            ; no, done
  476.  
  477. GetP1:    Lodsb
  478.     Cmp    AL,'/'            ;Switch char?
  479.     Je    GetP2
  480.     Jmp    Short GetP0
  481.  
  482. GetP2:    Cmp    SI,DI            ;Any string left?
  483.     Jae    GetPx            ; no, invalid option
  484. GetP2a:    Lodsb
  485.     Cmp    AL,'L'            ;Printer port?
  486.     Je    GetPl
  487.     Cmp    AL,'l'
  488.     Je    GetPl
  489.     Cmp    AL,'6'            ; for 6 lpi?
  490.     Je    GetP6
  491.     Cmp    AL,'8'            ; for 8 lpi?
  492.     Je    GetP8
  493.     Cmp    AL,'1'            ; for cpi?
  494.     Je    GetPc
  495.  
  496. GetPx:    Mov    DX,Offset ErrMsg    ; no, say INVALID OPTIONS
  497.     Jmp    Error
  498.  
  499. GetPl:    Cmp    SI,DI            ;Have next char?
  500.     Jae    GetPx
  501.     Lodsb
  502.     Cmp    AL,'1'            ;Valid printer?
  503.     Jb    GetPx
  504.     Cmp    AL,'2'
  505.     Ja    GetPx
  506.     Mov    Msg2a,AL        ; Put 'n' into message
  507.     Mov    Output+3,AL        ;  and into file name
  508.     Sub    AL,'1'            ; Form port address
  509.     Sub    AH,AH
  510.     Mov    LPTn,AX
  511.     Jmp    GetP0            ; try next field
  512.  
  513. GetP6:    Mov    LPP,60            ;Set 6 lpi
  514.     Mov    Lpi,54
  515.     Jmp    GetP0
  516.  
  517. GetP8:    Mov    LPP,82            ;Set 8 lpi
  518.     Mov    Lpi,56
  519.     Jmp    GetP0
  520.  
  521. GetPc:    Cmp    SI,DI            ;Any string left?
  522.     Jae    GetPx            ; no, invalid
  523.     Lodsb
  524. GetPc12:
  525.     Cmp    AL,'2'            ;Is it 12?
  526.     Jne    GetPc17
  527.     Mov    Cpp,96            ; chars per line
  528.     Mov    Cpi,28            ; printer control code
  529.     Mov    Tabs17,CR
  530.     Mov    Reset_L,Reset12
  531.     Jmp    GetPc2
  532. GetPc17:
  533.     Cmp    AL,'7'            ;Is it 17?
  534.     Jne    GetPc10
  535.     Mov    Cpp,136
  536.     Mov    Cpi,29
  537.     Mov    Reset_L,Reset17
  538.     Jmp    GetPc2
  539. GetPc10:
  540.     Cmp    AL,'0'            ;Is it 10?
  541.     Jne    GetPx            ; none of the above
  542.     Mov    Cpp,80
  543.     Mov    Cpi,30
  544.     Mov    Tabs12,CR
  545.     Mov    Reset_L,Reset10
  546.  
  547. GetPc2:
  548.     Jmp    GetP0            ; and try next switch
  549.  
  550. GetP9:    Pop    CX
  551.     Pop    SI
  552.     Pop    DI
  553.     Ret
  554. GetParm    Endp
  555.     Page
  556. ;
  557. ;    Ask for input file name
  558.  
  559. AskIn    Proc    Near
  560. Ask:    Mov    DX,Offset MsgIn        ;Prompt    msg for    input
  561.     Mov    AH,9            ;Print string
  562.     Int    21h
  563.  
  564.     Mov    InKey,64
  565.     Mov    DX,Offset InKey        ;Ptr to    keyboard buffer
  566.     Mov    AH,10            ;Buffered keyboard input
  567.     Int    21h
  568.     Sub    BX,BX            ;Clear for insert
  569.     Add    BL,InKey+1        ;Get length read
  570.     Jz    Ask            ;If nothing read
  571.     Mov    Byte Ptr Input[BX],0    ;Set ASCIIZ stopper
  572.     Mov    Word Ptr InKey,' :'    ;Clear error message part
  573.     Ret
  574. AskIn    Endp
  575.  
  576. GetFile    Endp
  577.     Page
  578. ;
  579. ;    Open files
  580.  
  581. Opens    Proc    Near
  582.     Mov    DX,Offset Input
  583.     Mov    AX,3D00h        ;Open for input
  584.     Int    21h
  585.     Jnc    Openi
  586.     Mov    DX,Offset Msg1
  587.     Jmp    Error
  588.  
  589. Openi:    Mov    IHandle,AX        ; Return input handle
  590.  
  591.     Mov    AX,4
  592.     Cmp    LPTn,0            ; Using standard printer?
  593.     Je    Openo
  594.     Mov    DX,Offset Output    ; Open LPTn
  595.     Mov    AX,3D01h        ;  for output
  596.     Int    21h
  597.     Jnc    Openo
  598.     Mov    DX,Offset Msg2        ; Open failed
  599.     Jmp    Error
  600.  
  601. Openo:    Mov    OHandle,AX        ; Return output handle
  602.     Ret
  603. Opens    Endp
  604.  
  605.  
  606. ;
  607. ;    Check DOS version
  608.  
  609. Ver    Proc    Near
  610.     Mov    AH,30h            ;Get DOS version
  611.     Int    21h
  612.     Cmp    AL,2            ;Rel 2 or later?
  613.     Jae    Ver1            ; if not
  614.     Mov    DX,Offset Sorry
  615.      Jmp    Error
  616.  
  617. Ver1:    Mov    DX,Offset Version
  618.     Mov    AH,9            ;Display title
  619.     Int    21h
  620.     Ret
  621.  
  622. Ver    Endp
  623.     Page
  624. ;
  625. ;    Allocate up to 32K for read buffer
  626.  
  627. Alloc    Proc    Near            ;Allocate storage
  628.     Mov    AH,4Ah            ;Modify allocated memory
  629.     Mov    BX,PgmSize        ;Length of Code and Stack
  630.     Int    21h
  631.  
  632.     Mov    BX,MaxSize        ;Try for 32K each
  633. Alloc1:    Mov    AH,48h
  634.     Int    21h
  635.     Jc    Alloc1            ;Failed, get what there is
  636.  
  637.     Sub    BX,MinSize        ;Safety pad
  638.     Cmp    BX,MinSize        ;Have enough?
  639.     Jb    Alloc9
  640.  
  641.     Mov    DX,CS            ;Get offset into DS
  642.     Sub    AX,DX            ; for input buffer
  643.     Mov    CL,4
  644.     Shl    AX,CL
  645.     Mov    InPtr,AX         ; Read buffer start
  646.     Mov    Iptr,AX            ;  and current char offset
  647.     Mov    OutPtr,AX        ; Write buffer offset
  648.     Mov    Optr,AX            ;  and next char offset
  649.  
  650.     Shr    BX,1            ; Split into two buffers
  651.     Mov    CL,4            ; Convert paras
  652.     Shl    BX,CL            ;  to bytes available
  653.     Mov    Buflen,BX
  654.     Mov    Olen,BX            ; Bytes avail in output buffer
  655.     Add    OutPtr,BX        ; Re-adjust output buffer
  656.     Add    Optr,BX
  657.  
  658.     Ret
  659.  
  660. Alloc9:    Mov    DX,Offset AlocMsg
  661.     Jmp    Error
  662. Alloc    Endp
  663.  
  664. LP    Endp
  665.  
  666. Lstack    Equ    $+128            ;End of local stack
  667.  
  668. PgmSize    Equ    ($-Cseg+16+128)/16    ;Size of program in paragraphs
  669. MaxSize    Equ    4096-PgmSize        ;Paras left in segment
  670. MinSize    Equ    32            ;Minimum buffer needed
  671.  
  672. Cseg    Ends
  673.  
  674.     End    LP
  675.